package sk.stuba.fiit.pki.dao.impl;

import java.math.BigInteger;
import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import sk.stuba.fiit.pki.dao.CertificateDao;
import sk.stuba.fiit.pki.entity.CertificateEntity;
import sk.stuba.fiit.pki.entity.SerialSeqEntity;
import sk.stuba.fiit.pki.service.SerialService;

@Repository("certificateDao")
@Transactional(readOnly = true)
public class CertificateDaoImpl implements CertificateDao {

	protected HibernateTemplate template = null;
	
	@Autowired
	protected SessionFactory sessionFactory = null;

	/**
	 * Sets Hibernate session factory.
	 */
	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		template = new HibernateTemplate(sessionFactory);
	}
	
	@SuppressWarnings("unchecked")
	public List<CertificateEntity> findCertificates()
			throws DataAccessException {
		return template.find("from CERTIFICATE");
	}
	
	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void save(CertificateEntity certificateEntity) {
		template.saveOrUpdate(certificateEntity);	
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void delete(CertificateEntity certificateEntity) {
		template.delete(certificateEntity);
		
	}

	public CertificateEntity findCertificateBySerialNumber(BigInteger id, String issuer)
			throws DataAccessException {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Criteria criteria = session.createCriteria(CertificateEntity.class).add(Restrictions.eq("serialNumber", id));
		List<CertificateEntity> result = criteria.list();
		transaction.rollback();
		session.close();
		if(result.size()==1)
			return result.get(0);
		 return new CertificateEntity();
	}
	
	public CertificateEntity findCertificateBySubjectIssuer(String subject) {
		Session session = sessionFactory.openSession();
		String findTemplate = subject.replace("=", "\\=").replace(",", "\\,").replace("CN\\=", "CN=").replace("\"", "");
		Transaction transaction = session.beginTransaction();
		Criteria criteria = session.createCriteria(CertificateEntity.class).add(Restrictions.eq("subject", findTemplate));
		List<CertificateEntity> result = criteria.list();
		transaction.rollback();
		session.close();
		if(result.size()==1)
			return result.get(0);
		 return new CertificateEntity();
	}

	public List<CertificateEntity> findRevocateCertificate() {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		List<CertificateEntity> revCertq = (List<CertificateEntity>) session.createCriteria(CertificateEntity.class).add( Restrictions.eq("revocate",true)).list();
		transaction.rollback();
		session.close();
		return revCertq;
	}


}
